#include "mesh.h"
#include "geometry.h"

namespace sleek
{
    namespace mesh
    {
        Geometry::Geometry()
        {
        }
        Geometry::~Geometry()
        {
        }
        MeshBuffer* Geometry::createPlane(core::math::vector2df size, core::u32 polyCountX, core::u32 polyCountY, texture::pixel color)
        {
            MeshBuffer *tmp = new MeshBuffer();
                tmp->vertices.set_used(4);
                    tmp->vertices[0].Pos = core::math::vector3df(-size.width/2, 0,-size.height/2);
                    tmp->vertices[1].Pos = core::math::vector3df( size.width/2, 0,-size.height/2);
                    tmp->vertices[2].Pos = core::math::vector3df( size.width/2, 0, size.height/2);
                    tmp->vertices[3].Pos = core::math::vector3df(-size.width/2, 0, size.height/2);

                    tmp->vertices[0].Coord = core::math::vector2df(0.0f, 0.0f);
                    tmp->vertices[1].Coord = core::math::vector2df(1.0f, 0.0f);
                    tmp->vertices[2].Coord = core::math::vector2df(1.0f, 1.0f);
                    tmp->vertices[3].Coord = core::math::vector2df(0.0f, 1.0f);

                    tmp->vertices[0].Normal = core::math::vector3df( 0.0f, 1.0f, 0.f);
                    tmp->vertices[1].Normal = core::math::vector3df( 0.0f, 1.0f, 0.f);
                    tmp->vertices[2].Normal = core::math::vector3df( 0.0f, 1.0f, 0.f);
                    tmp->vertices[3].Normal = core::math::vector3df( 0.0f, 1.0f, 0.f);

                    tmp->vertices[ 0].Color = color; tmp->vertices[ 1].Color = color;
                    tmp->vertices[ 2].Color = color; tmp->vertices[ 3].Color = color;
                tmp->indices.set_used(2);
                    tmp->indices[0] = mesh::index(0,2,1);
                    tmp->indices[1] = mesh::index(0,3,2);
            return tmp;
        }
        MeshBuffer* Geometry::createWall(core::math::vector2df size, texture::pixel color)
        {
            MeshBuffer *tmp = new MeshBuffer();
                tmp->vertices.set_used(4);
                    tmp->vertices[0].Pos = core::math::vector3df(-size.width/2,-size.height/2, 0);
                    tmp->vertices[1].Pos = core::math::vector3df( size.width/2,-size.height/2, 0);
                    tmp->vertices[2].Pos = core::math::vector3df( size.width/2, size.height/2, 0);
                    tmp->vertices[3].Pos = core::math::vector3df(-size.width/2, size.height/2, 0);

                    tmp->vertices[0].Coord = core::math::vector2df(0.0f, 0.0f);
                    tmp->vertices[1].Coord = core::math::vector2df(1.0f, 0.0f);
                    tmp->vertices[2].Coord = core::math::vector2df(1.0f, 1.0f);
                    tmp->vertices[3].Coord = core::math::vector2df(0.0f, 1.0f);

                    tmp->vertices[0].Normal = core::math::vector3df( 0.0f, 0.0f, 1.f);
                    tmp->vertices[1].Normal = core::math::vector3df( 0.0f, 0.0f, 1.f);
                    tmp->vertices[2].Normal = core::math::vector3df( 0.0f, 0.0f, 1.f);
                    tmp->vertices[3].Normal = core::math::vector3df( 0.0f, 0.0f, 1.f);

                    tmp->vertices[ 0].Color = color; tmp->vertices[ 1].Color = color;
                    tmp->vertices[ 2].Color = color; tmp->vertices[ 3].Color = color;
                tmp->indices.set_used(2);
                    tmp->indices[0] = mesh::index(0,2,1);
                    tmp->indices[1] = mesh::index(0,3,2);
            return tmp;
        }
        MeshBuffer* Geometry::createCircle(core::math::vector2df radiusxy, core::f32 step_x, core::f32 step_y, texture::pixel color)
        {
            MeshBuffer *tmp = new MeshBuffer();
                tmp->vertices.set_used(step_x*step_y+1);
                register unsigned short psize = 0;
                register float anglex = 0.f, angley = 0.f;
                for(register float x = 0.f; x<step_x; ++x)
                {
                    anglex += radiusxy.width;
                    for(register float y = 0.f; x<step_y; ++y)
                    {
                        angley += radiusxy.height;
                        tmp->vertices[psize].Pos = core::math::vector3df(sin(anglex), 0, cos(angley));
                        psize++;
                    }
                }
                tmp->updateNormal();
            return tmp;
        }
        MeshBuffer* Geometry::createSphere(core::f32 radius, core::u32 polyCountX, core::u32 polyCountY, texture::pixel color)
        {
            MeshBuffer *tmp = new MeshBuffer();
                tmp->vertices.set_used(polyCountX*polyCountY);
                tmp->updateNormal();
            return tmp;
        }
        MeshBuffer* Geometry::createCube(core::math::vector3df size, texture::pixel color)
        {
            MeshBuffer *tmp = new MeshBuffer();
                tmp->vertices.set_used(24);
                    tmp->vertices[ 0].Pos = core::math::vector3df(-size.x/2,-size.y/2, size.z/2);
                    tmp->vertices[ 1].Pos = core::math::vector3df( size.x/2,-size.y/2, size.z/2);
                    tmp->vertices[ 2].Pos = core::math::vector3df( size.x/2, size.y/2, size.z/2);
                    tmp->vertices[ 3].Pos = core::math::vector3df(-size.x/2, size.y/2, size.z/2);
                    tmp->vertices[ 4].Pos = core::math::vector3df(-size.x/2,-size.y/2,-size.z/2);
                    tmp->vertices[ 5].Pos = core::math::vector3df(-size.x/2, size.y/2,-size.z/2);
                    tmp->vertices[ 6].Pos = core::math::vector3df( size.x/2, size.y/2,-size.z/2);
                    tmp->vertices[ 7].Pos = core::math::vector3df( size.x/2,-size.y/2,-size.z/2);
                    tmp->vertices[ 8].Pos = core::math::vector3df(-size.x/2, size.y/2,-size.z/2);
                    tmp->vertices[ 9].Pos = core::math::vector3df(-size.x/2, size.y/2, size.z/2);
                    tmp->vertices[10].Pos = core::math::vector3df( size.x/2, size.y/2, size.z/2);
                    tmp->vertices[11].Pos = core::math::vector3df( size.x/2, size.y/2,-size.z/2);
                    tmp->vertices[12].Pos = core::math::vector3df(-size.x/2,-size.y/2,-size.z/2);
                    tmp->vertices[13].Pos = core::math::vector3df( size.x/2,-size.y/2,-size.z/2);
                    tmp->vertices[14].Pos = core::math::vector3df( size.x/2,-size.y/2, size.z/2);
                    tmp->vertices[15].Pos = core::math::vector3df(-size.x/2,-size.y/2, size.z/2);
                    tmp->vertices[16].Pos = core::math::vector3df( size.x/2,-size.y/2,-size.z/2);
                    tmp->vertices[17].Pos = core::math::vector3df( size.x/2, size.y/2,-size.z/2);
                    tmp->vertices[18].Pos = core::math::vector3df( size.x/2, size.y/2, size.z/2);
                    tmp->vertices[19].Pos = core::math::vector3df( size.x/2,-size.y/2, size.z/2);
                    tmp->vertices[20].Pos = core::math::vector3df(-size.x/2,-size.y/2,-size.z/2);
                    tmp->vertices[21].Pos = core::math::vector3df(-size.x/2,-size.y/2, size.z/2);
                    tmp->vertices[22].Pos = core::math::vector3df(-size.x/2, size.y/2, size.z/2);
                    tmp->vertices[23].Pos = core::math::vector3df(-size.x/2, size.y/2,-size.z/2);

                    tmp->vertices[ 0].Coord = core::math::vector2df(0.0f, 0.0f);
                    tmp->vertices[ 1].Coord = core::math::vector2df(1.0f, 0.0f);
                    tmp->vertices[ 2].Coord = core::math::vector2df(1.0f, 1.0f);
                    tmp->vertices[ 3].Coord = core::math::vector2df(0.0f, 1.0f);
                    tmp->vertices[ 4].Coord = core::math::vector2df(1.0f, 0.0f);
                    tmp->vertices[ 5].Coord = core::math::vector2df(1.0f, 1.0f);
                    tmp->vertices[ 6].Coord = core::math::vector2df(0.0f, 1.0f);
                    tmp->vertices[ 7].Coord = core::math::vector2df(0.0f, 0.0f);
                    tmp->vertices[ 8].Coord = core::math::vector2df(0.0f, 1.0f);
                    tmp->vertices[ 9].Coord = core::math::vector2df(0.0f, 0.0f);
                    tmp->vertices[10].Coord = core::math::vector2df(1.0f, 0.0f);
                    tmp->vertices[11].Coord = core::math::vector2df(1.0f, 1.0f);
                    tmp->vertices[12].Coord = core::math::vector2df(1.0f, 1.0f);
                    tmp->vertices[13].Coord = core::math::vector2df(0.0f, 1.0f);
                    tmp->vertices[14].Coord = core::math::vector2df(0.0f, 0.0f);
                    tmp->vertices[15].Coord = core::math::vector2df(1.0f, 0.0f);
                    tmp->vertices[16].Coord = core::math::vector2df(1.0f, 0.0f);
                    tmp->vertices[17].Coord = core::math::vector2df(1.0f, 1.0f);
                    tmp->vertices[18].Coord = core::math::vector2df(0.0f, 1.0f);
                    tmp->vertices[19].Coord = core::math::vector2df(0.0f, 0.0f);
                    tmp->vertices[20].Coord = core::math::vector2df(0.0f, 0.0f);
                    tmp->vertices[21].Coord = core::math::vector2df(1.0f, 0.0f);
                    tmp->vertices[22].Coord = core::math::vector2df(1.0f, 1.0f);
                    tmp->vertices[23].Coord = core::math::vector2df(0.0f, 1.0f);

                    tmp->vertices[ 0].Normal = core::math::vector3df( 0.0f, 0.0f, 1.f);
                    tmp->vertices[ 1].Normal = core::math::vector3df( 0.0f, 0.0f, 1.f);
                    tmp->vertices[ 2].Normal = core::math::vector3df( 0.0f, 0.0f, 1.f);
                    tmp->vertices[ 3].Normal = core::math::vector3df( 0.0f, 0.0f, 1.f);
                    tmp->vertices[ 4].Normal = core::math::vector3df( 0.0f, 0.0f,-1.0f);
                    tmp->vertices[ 5].Normal = core::math::vector3df( 0.0f, 0.0f,-1.0f);
                    tmp->vertices[ 6].Normal = core::math::vector3df( 0.0f, 0.0f,-1.0f);
                    tmp->vertices[ 7].Normal = core::math::vector3df( 0.0f, 0.0f,-1.0f);
                    tmp->vertices[ 8].Normal = core::math::vector3df( 0.0f, 1.0f, 0.0f);
                    tmp->vertices[ 9].Normal = core::math::vector3df( 0.0f, 1.0f, 0.0f);
                    tmp->vertices[10].Normal = core::math::vector3df( 0.0f, 1.0f, 0.0f);
                    tmp->vertices[11].Normal = core::math::vector3df( 0.0f, 1.0f, 0.0f);
                    tmp->vertices[12].Normal = core::math::vector3df( 0.0f,-1.0f, 0.0f);
                    tmp->vertices[13].Normal = core::math::vector3df( 0.0f,-1.0f, 0.0f);
                    tmp->vertices[14].Normal = core::math::vector3df( 0.0f,-1.0f, 0.0f);
                    tmp->vertices[15].Normal = core::math::vector3df( 0.0f,-1.0f, 0.0f);
                    tmp->vertices[16].Normal = core::math::vector3df( 1.0f, 0.0f, 0.0f);
                    tmp->vertices[17].Normal = core::math::vector3df( 1.0f, 0.0f, 0.0f);
                    tmp->vertices[18].Normal = core::math::vector3df( 1.0f, 0.0f, 0.0f);
                    tmp->vertices[19].Normal = core::math::vector3df( 1.0f, 0.0f, 0.0f);
                    tmp->vertices[20].Normal = core::math::vector3df(-1.0f, 0.0f, 0.0f);
                    tmp->vertices[21].Normal = core::math::vector3df(-1.0f, 0.0f, 0.0f);
                    tmp->vertices[22].Normal = core::math::vector3df(-1.0f, 0.0f, 0.0f);
                    tmp->vertices[23].Normal = core::math::vector3df(-1.0f, 0.0f, 0.0f);

                    tmp->vertices[ 0].Color = color; tmp->vertices[ 1].Color = color;
                    tmp->vertices[ 2].Color = color; tmp->vertices[ 3].Color = color;
                    tmp->vertices[ 4].Color = color; tmp->vertices[ 5].Color = color;
                    tmp->vertices[ 6].Color = color; tmp->vertices[ 7].Color = color;
                    tmp->vertices[ 8].Color = color; tmp->vertices[ 9].Color = color;
                    tmp->vertices[10].Color = color; tmp->vertices[11].Color = color;
                    tmp->vertices[12].Color = color; tmp->vertices[13].Color = color;
                    tmp->vertices[14].Color = color; tmp->vertices[15].Color = color;
                    tmp->vertices[16].Color = color; tmp->vertices[17].Color = color;
                    tmp->vertices[18].Color = color; tmp->vertices[19].Color = color;
                    tmp->vertices[20].Color = color; tmp->vertices[21].Color = color;
                    tmp->vertices[22].Color = color; tmp->vertices[23].Color = color;
                tmp->indices.set_used(12);
                    tmp->indices[ 0] = mesh::index( 0, 2, 1);
                    tmp->indices[ 1] = mesh::index( 0, 3, 2);
                    tmp->indices[ 2] = mesh::index( 4, 6, 5);
                    tmp->indices[ 3] = mesh::index( 4, 7, 6);
                    tmp->indices[ 4] = mesh::index( 8,10, 9);
                    tmp->indices[ 5] = mesh::index( 8,11,10);
                    tmp->indices[ 6] = mesh::index(12,14,13);
                    tmp->indices[ 7] = mesh::index(12,15,14);
                    tmp->indices[ 8] = mesh::index(16,18,17);
                    tmp->indices[ 9] = mesh::index(16,19,18);
                    tmp->indices[10] = mesh::index(20,22,21);
                    tmp->indices[11] = mesh::index(20,23,22);
                tmp->updateNormal();
            return tmp;
        }
        MeshBuffer* Geometry::createPolygone(core::math::vector3df a,core::math::vector3df b,core::math::vector3df c, texture::pixel color)
        {
            MeshBuffer *tmp = new MeshBuffer();
                tmp->vertices.set_used(3);
                    tmp->vertices[0].Pos = a;
                    tmp->vertices[1].Pos = b;
                    tmp->vertices[2].Pos = c;
                    tmp->vertices[ 0].Color = color;
                    tmp->vertices[ 1].Color = color;
                    tmp->vertices[ 2].Color = color;
                    tmp->vertices[ 3].Color = color;
                tmp->indices.set_used(1);
                    tmp->indices[ 0] = mesh::index(0, 1, 2);
                tmp->updateNormal();
            return tmp;
        }
        MeshBuffer* Geometry::createPyramid(core::math::vector3df size, texture::pixel color)
        {
            MeshBuffer *tmp = new MeshBuffer();
                tmp->vertices.set_used(16);
                    tmp->vertices[ 0].Pos = core::math::vector3df(-size.x/2,-size.y/2,-size.z/2);
                    tmp->vertices[ 1].Pos = core::math::vector3df( size.x/2,-size.y/2,-size.z/2);
                    tmp->vertices[ 2].Pos = core::math::vector3df( size.x/2,-size.y/2, size.z/2);
                    tmp->vertices[ 3].Pos = core::math::vector3df(-size.x/2,-size.y/2, size.z/2);
                    tmp->vertices[ 4].Pos = core::math::vector3df(-size.x/2,-size.y/2,-size.z/2);
                    tmp->vertices[ 5].Pos = core::math::vector3df( size.x/2,-size.y/2,-size.z/2);
                    tmp->vertices[ 6].Pos = core::math::vector3df(        0, size.y/2,        0);
                    tmp->vertices[ 7].Pos = core::math::vector3df( size.x/2,-size.y/2,-size.z/2);
                    tmp->vertices[ 8].Pos = core::math::vector3df( size.x/2,-size.y/2, size.z/2);
                    tmp->vertices[ 9].Pos = core::math::vector3df(        0, size.y/2,        0);
                    tmp->vertices[10].Pos = core::math::vector3df( size.x/2,-size.y/2, size.z/2);
                    tmp->vertices[11].Pos = core::math::vector3df(-size.x/2,-size.y/2, size.z/2);
                    tmp->vertices[12].Pos = core::math::vector3df(        0, size.y/2,        0);
                    tmp->vertices[13].Pos = core::math::vector3df(-size.x/2,-size.y/2,-size.z/2);
                    tmp->vertices[14].Pos = core::math::vector3df(-size.x/2,-size.y/2, size.z/2);
                    tmp->vertices[15].Pos = core::math::vector3df(        0, size.y/2,        0);

                    tmp->vertices[ 0].Coord = core::math::vector2df(1.0f, 1.0f);
                    tmp->vertices[ 1].Coord = core::math::vector2df(0.0f, 1.0f);
                    tmp->vertices[ 2].Coord = core::math::vector2df(0.0f, 0.0f);
                    tmp->vertices[ 3].Coord = core::math::vector2df(1.0f, 0.0f);
                    tmp->vertices[ 4].Coord = core::math::vector2df(0.0f, 0.0f);
                    tmp->vertices[ 5].Coord = core::math::vector2df(1.0f, 0.0f);
                    tmp->vertices[ 6].Coord = core::math::vector2df(0.5f, 1.0f);
                    tmp->vertices[ 7].Coord = core::math::vector2df(0.0f, 0.0f);
                    tmp->vertices[ 8].Coord = core::math::vector2df(1.0f, 0.0f);
                    tmp->vertices[ 9].Coord = core::math::vector2df(0.5f, 1.0f);
                    tmp->vertices[10].Coord = core::math::vector2df(0.0f, 0.0f);
                    tmp->vertices[11].Coord = core::math::vector2df(1.0f, 0.0f);
                    tmp->vertices[12].Coord = core::math::vector2df(0.5f, 1.0f);
                    tmp->vertices[13].Coord = core::math::vector2df(0.0f, 0.0f);
                    tmp->vertices[14].Coord = core::math::vector2df(1.0f, 0.0f);
                    tmp->vertices[15].Coord = core::math::vector2df(0.5f, 1.0f);

                    tmp->vertices[ 0].Normal = core::math::vector3df( 0.0f,-1.0f, 0.0f);
                    tmp->vertices[ 1].Normal = core::math::vector3df( 0.0f,-1.0f, 0.0f);
                    tmp->vertices[ 2].Normal = core::math::vector3df( 0.0f,-1.0f, 0.0f);
                    tmp->vertices[ 3].Normal = core::math::vector3df( 0.0f,-1.0f, 0.0f);
                    tmp->vertices[ 4].Normal = core::math::vector3df(-1.0f,-1.0f,-1.0f);
                    tmp->vertices[ 5].Normal = core::math::vector3df( 1.0f,-1.0f,-1.0f);
                    tmp->vertices[ 6].Normal = core::math::vector3df( 0.0f, 1.0f, 0.0f);
                    tmp->vertices[ 7].Normal = core::math::vector3df( 1.0f,-1.0f,-1.0f);
                    tmp->vertices[ 8].Normal = core::math::vector3df( 1.0f,-1.0f, 1.0f);
                    tmp->vertices[ 9].Normal = core::math::vector3df( 0.0f, 1.0f, 0.0f);
                    tmp->vertices[10].Normal = core::math::vector3df( 1.0f,-1.0f, 1.0f);
                    tmp->vertices[11].Normal = core::math::vector3df(-1.0f,-1.0f, 1.0f);
                    tmp->vertices[12].Normal = core::math::vector3df( 0.0f, 1.0f, 0.0f);
                    tmp->vertices[13].Normal = core::math::vector3df(-1.0f,-1.0f,-1.0f);
                    tmp->vertices[14].Normal = core::math::vector3df(-1.0f,-1.0f, 1.0f);
                    tmp->vertices[15].Normal = core::math::vector3df( 0.0f, 1.0f, 0.0f);

                    tmp->vertices[ 0].Color = color; tmp->vertices[ 1].Color = color;
                    tmp->vertices[ 2].Color = color; tmp->vertices[ 3].Color = color;
                    tmp->vertices[ 4].Color = color; tmp->vertices[ 5].Color = color;
                    tmp->vertices[ 6].Color = color; tmp->vertices[ 7].Color = color;
                    tmp->vertices[ 8].Color = color; tmp->vertices[ 9].Color = color;
                    tmp->vertices[10].Color = color; tmp->vertices[11].Color = color;
                    tmp->vertices[12].Color = color; tmp->vertices[13].Color = color;
                    tmp->vertices[14].Color = color; tmp->vertices[15].Color = color;
                tmp->indices.set_used(6);
                    tmp->indices[ 0] = mesh::index( 0, 2, 1);
                    tmp->indices[ 1] = mesh::index( 0, 3, 2);
                    tmp->indices[ 2] = mesh::index( 4, 5, 6);
                    tmp->indices[ 3] = mesh::index( 7, 8, 9);
                    tmp->indices[ 4] = mesh::index(10,11,12);
                    tmp->indices[ 5] = mesh::index(13,14,15);
            return tmp;
        }
        MeshBuffer* Geometry::createTorus(core::f32 radiusX, core::f32 radiusY, core::u32 polyCountX, core::u32 polyCountY, texture::pixel color)
        {
            MeshBuffer *tmp = new MeshBuffer();
                tmp->updateNormal();
            return tmp;
        }
        MeshBuffer* Geometry::createCone(core::f32 radius, core::f32 length, core::u32 tesselation, texture::pixel color)
        {
            MeshBuffer *tmp = new MeshBuffer();
                tmp->updateNormal();
            return tmp;
        }
        MeshBuffer* Geometry::createCylindre(core::f32 radius, core::f32 length, core::u32 tesselation, texture::pixel color)
        {
            MeshBuffer *tmp = new MeshBuffer();
                tmp->updateNormal();
            return tmp;
        }
    }
}
